package liangtWorkSpace.lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @ClassName ConsumerMain
 * @Description : 简单演示java.util.Function自带函数式接口中的部分示例
 * @Author : LiangT
 * @Date : 2020/4/17 16:17
 */
public class ConsumerMain  {
    private static int number = 123;
    /**
     * Consumer.accept接口实现了
     *  T->void类型
     * @param list
     * @param c
     * @param <T>
     */
    public static <T> void forEach(List<T> list, Consumer<T> c){
        for (T t: list){
            c.accept(t);
        }
    }

    /**
     * Supplier.get()实现了
     * ()->T 类型。获取一个新的对象
     * @param a
     * @param <T>
     * @return
     */
    public static <T> T getObject(Supplier<T> a){
        return a.get();
    }

    /**
     * Lambda可以引用局部变量，但是不能使用赋值操作，即不能改变变量本身
     * Lambda引用必须是final的或者叫事实上final的,即你只能对他赋值一次，二次赋值的变量不能在Lambda中引用
     *
     */
    public static void runnable(){
        int i = 1000;
        Runnable runnable = ()-> System.out.println("是个数字："+i + "number:"+number);
        number = 456;

    }

    /**
     * Lambda的方法引用
     */
    public static void length(){
        List<String> str = Arrays.asList("a","b","A","B");

        str.sort((s1,s2)->s1.compareToIgnoreCase(s2));
        System.out.println(Arrays.toString(str.toArray()));
        str = Arrays.asList("a","b","A","B");
        str.sort(String::compareToIgnoreCase);
        System.out.println(Arrays.toString(str.toArray()));

    }

    /**
     * 方法引用--构造函数的方法引用
     */
    public static void gz(){
        //等于又一个匿名类把Supplier接口的get方式实现了。
        //可以等同于
        Supplier<String> stringSupplierS = new Supplier<String>() {
            @Override
            public String get() {
                return new String();
            }
        };
        Supplier<Apple> integerSupplier = Apple::new;
        Supplier<String> stringSupplier = String::new;
        String s = stringSupplier.get();
        Apple a = integerSupplier.get();

        //同样使用(T,R)->T可以实现对Integer实现
        Supplier<Integer> integerSupplier1 = ()->new Integer(123);
        Integer integer = integerSupplier1.get();
        Function<Integer,Integer> function1 = Integer::new;
        Function<Integer,Integer> function2 = (Integer i)->new Integer(i);

        Integer integer1 = function1.apply(123);
        Integer integer2 = function2.apply(123);
        Integer integer3 = new Function<Integer, Integer>(){
            @Override
            public Integer apply(Integer integer) {
                return integer;
            }
        }.apply(123);
        //使用(T,R,X)->x实现对Apple实例化
        BiFunction<Integer,String,Apple> biFunction = (color,weight)->new Apple(color,weight);
        Apple apple = biFunction.apply(123,"green");

        //利用Function获取一列苹果
        List<Integer> weight = Arrays.asList(1,2,3,4);
        List<Apple> appleList = map(weight,Apple::new);
        System.out.println(Arrays.toString(appleList.toArray()));
    }
    //利用Function获取对象数组
    private static <T ,R> List<T> map(List<R> list,Function<R,T> function){
        List<T> result = new ArrayList();
        for (R r:list){
            result.add(function.apply(r));
        }
        return result;
    }
    public static void main(String[] args) {
        forEach(Arrays.asList(1,2,3,4,5),(Integer i)->{
            int length = getObject(()-> {
                return 123;
            });
        });

        System.out.println(getObject(()->"验证Supplier信息"));;
        runnable();
        length();
        gz();
    }
}
